package dao;

import java.util.ArrayList;
import java.util.List;
import model.Acao;
import model.Usuario;
import model.UsuarioAcao;
import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;
import util.CustomException;

public class UsuarioAcaoDAO extends GenericEntityDAO<UsuarioAcao, Long> {

    public List<UsuarioAcao> selecionarPorUsuario(Session session, Usuario usuario) throws CustomException {
        List<UsuarioAcao> usuarioAcaoList = new ArrayList();
        try {
            Criteria criteria = session.createCriteria(UsuarioAcao.class, "usuarioAcao");
            criteria.createAlias("usuarioAcao.acao", "acao"); // INNER JOIN ACAO
            criteria.createAlias("acao.acaoGrupo", "acaoGrupo"); // INNER JOIN ACAO_GRUPO
            criteria.createAlias("usuarioAcao.usuario", "usuario"); // INNER JOIN USUARIO
            criteria.add(Restrictions.eq("usuario.usuCodigo", usuario.getUsuCodigo()));
            criteria.add(Restrictions.eq("acao.acaoAtivo", Boolean.TRUE));
            criteria.add(Restrictions.eq("acaoGrupo.agrAtivo", Boolean.TRUE));
            usuarioAcaoList.addAll(criteria.list());

            List<Long> acaoCodigoList = new ArrayList();
            for (UsuarioAcao usuarioAcao : usuarioAcaoList) {
                acaoCodigoList.add(usuarioAcao.getAcao().getAcaoCodigo());
            }

            criteria = session.createCriteria(Acao.class, "acao");
            criteria.createAlias("acao.acaoGrupo", "acaoGrupo"); // INNER JOIN ACAO_GRUPO
            if (!acaoCodigoList.isEmpty()) {
                criteria.add(Restrictions.not(Restrictions.in("acaoCodigo", acaoCodigoList)));
            }
            criteria.add(Restrictions.eq("acao.acaoAtivo", Boolean.TRUE));
            criteria.add(Restrictions.eq("acaoGrupo.agrAtivo", Boolean.TRUE));

            List<Acao> acaoList = criteria.list();
            for (Acao acao : acaoList) {
                usuarioAcaoList.add(new UsuarioAcao(0, usuario, acao, Boolean.FALSE));
            }
        } catch (Exception e) {
            throw new CustomException("Falha ao selecionar ações do usuário.", e);
        }
        return usuarioAcaoList;
    }

    public List<UsuarioAcao> selecionarPorNovoUsuario(Session session, Usuario usuario) throws CustomException {
        List<UsuarioAcao> usuarioAcaoList = new ArrayList();
        try {
            Criteria criteria = session.createCriteria(Acao.class, "acao");
            criteria.createAlias("acao.acaoGrupo", "acaoGrupo"); // INNER JOIN ACAO_GRUPO
            criteria.add(Restrictions.eq("acao.acaoAtivo", Boolean.TRUE));
            criteria.add(Restrictions.eq("acaoGrupo.agrAtivo", Boolean.TRUE));
            criteria.addOrder(Order.asc("agrNome"));
            criteria.addOrder(Order.asc("acaoDescricao"));
            List<Acao> acaoList = criteria.list();
            for (Acao acao : acaoList) {
                usuarioAcaoList.add(new UsuarioAcao(0, usuario, acao, Boolean.FALSE));
            }
        } catch (Exception e) {
            throw new CustomException("Falha ao selecionar ações do usuário.", e);
        }
        return usuarioAcaoList;
    }
}
